#include "brick.h"

#include "tetris.h"

static brick_shape s_brick_shape[SHAPE_MAX] = {
  {
    { 0, 1, 0, 0 },
    { 0, 1, 0, 0 },
    { 0, 1, 0, 0 },
    { 0, 1, 0, 0 },
  },
  {            
    { 0, 0, 0, 0 },
    { 0, 1, 1, 0 },
    { 0, 1, 1, 0 },
    { 0, 0, 0, 0 },
  },
  {            
    { 0, 1, 1, 0 },
    { 0, 0, 1, 0 },
    { 0, 0, 1, 0 },
    { 0, 0, 0, 0 },
  },
  {
    { 0, 1, 1, 0 },
    { 0, 1, 0, 0 },
    { 0, 1, 0, 0 },
    { 0, 0, 0, 0 },
  },
  {
    { 0, 0, 0, 0 },
    { 1, 1, 0, 0 },
    { 0, 1, 1, 0 },
    { 0, 0, 0, 0 },
  },
  {
    { 0, 0, 0, 0 },
    { 0, 1, 1, 0 },
    { 1, 1, 0, 0 },
    { 0, 0, 0, 0 },
  },
  {
    { 0, 0, 0, 0 },
    { 0, 1, 0, 0 },
    { 1, 1, 1, 0 },
    { 0, 0, 0, 0 },
  }
};

struct brick_info* create_brick(int tile, int shape)
{
  struct brick_info* brick = (struct brick_info*)malloc(sizeof(*brick));
  brick->tile_index = tile;
  if (shape < 0 || shape >= SHAPE_MAX) {
    shape = 0;
  }
  memcpy(brick->shape, s_brick_shape[shape], sizeof(brick->shape));
  return (brick);
}

void change_shape(struct brick_info* brick, int tile, int shape)
{
  brick->tile_index = tile;
  if (shape < 0 || shape >= SHAPE_MAX) {
    shape = 0;
  }
  memcpy(brick->shape, s_brick_shape[shape], sizeof(brick->shape));
}

void change_direction(struct brick_info* brick)
{
  int i, j;
  brick_shape shape;
  for (i = 0; i < BRICK_RANGE; i++) {
    for (j = 0; j < BRICK_RANGE; j++) {
      shape[i][j] = brick->shape[j][3 - i];
    }
  }
  memcpy(brick->shape, shape, sizeof(brick->shape));
}

void move_brick_left(struct brick_info* brick)
{
  int x, y;
  for (y = 0; y < BRICK_RANGE; y++) {
    if (brick->shape[y][0] != 0) {
      return;
    }
  }
  // move the brick left
  for (y = 0; y < BRICK_RANGE; y++) {
    for (x = 0; x < BRICK_RANGE - 1; x++) {
      brick->shape[y][x] = brick->shape[y][x + 1];
    }
    brick->shape[y][BRICK_RANGE - 1] = 0;
  }
}

void move_brick_right(struct brick_info* brick)
{
  int x, y;
  for (y = 0; y < BRICK_RANGE; y++) {
    if (brick->shape[y][BRICK_RANGE - 1] != 0) {
      return;
    }
  }
  // move the brick right
  for (y = 0; y < BRICK_RANGE; y++) {
    for (x = BRICK_RANGE - 1; x > 0; x--) {
      brick->shape[y][x] = brick->shape[y][x - 1];
    }
    brick->shape[y][0] = 0;
  }
}

void destroy_brick(struct brick_info* brick)
{
  free(brick);
}
